﻿Namespace EIB.Bus.FT12
    Public NotInheritable Class FT12_FrameVariable
        Inherits FT12_FrameControl

        Private _dataLength As Byte = Nothing
        Private _data As Byte() = Nothing


        Sub New(direction As FT12_FrameDirection, toggleFCB As Boolean, FCV As Boolean, messageCode As Byte, data As Byte())
            MyBase.New(FT12_FrameType.Variable, direction, toggleFCB, FCV, messageCode)

            _dataLength = data.Length + 1
            _data = data

            Dim ft12data As Byte() = New Byte(6 + _dataLength - 1) {}
            ft12data(0) = FT12_FrameBase.FT12_STARTVARIABLE
            ft12data(1) = _dataLength
            ft12data(2) = _dataLength
            ft12data(3) = FT12_FrameBase.FT12_STARTVARIABLE
            ft12data(4) = _Control

            For i = 0 To data.Length - 1
                ft12data(5 + i) = data(i)
            Next

            ft12data(ft12data.Length - 2) = CalculateCheckSum(ft12data)
            ft12data(ft12data.Length - 1) = FT12_FrameBase.FT12_END

            _FT12_Data = ft12data
        End Sub

        Sub New(direction As FT12_FrameDirection, dataFlowControl As Boolean, messageCode As Byte, data As Byte())
            MyBase.New(FT12_FrameType.Variable, direction, dataFlowControl, messageCode)

            _dataLength = data.Length + 1
            _data = data

            Dim ft12data As Byte() = New Byte(6 + _dataLength - 1) {}
            ft12data(0) = FT12_FrameBase.FT12_STARTVARIABLE
            ft12data(1) = _dataLength
            ft12data(2) = _dataLength
            ft12data(3) = FT12_FrameBase.FT12_STARTVARIABLE
            ft12data(4) = _Control

            For i = 0 To data.Length - 1
                ft12data(5 + i) = data(i)
            Next

            ft12data(ft12data.Length - 2) = CalculateCheckSum(ft12data)
            ft12data(ft12data.Length - 1) = FT12_FrameBase.FT12_END

            _FT12_Data = ft12data
        End Sub

        Sub New(busData As Byte())
            MyBase.New(busData, 4)

            If busData(0) <> FT12_FrameBase.FT12_STARTVARIABLE Then Throw New EIB.Exceptions.EIBDataDecodeException("")
            If busData(3) <> FT12_FrameBase.FT12_STARTVARIABLE Then Throw New EIB.Exceptions.EIBDataDecodeException("")
            If busData(1) <> busData(2) Then Throw New EIB.Exceptions.EIBDataDecodeException("")
            If busData.Length <> busData(1) + 6 Then Throw New EIB.Exceptions.EIBDataDecodeException("")
            If busData(busData.Length - 1) <> FT12_FrameBase.FT12_END Then Throw New EIB.Exceptions.EIBDataDecodeException("")
            If CalculateCheckSum(busData) <> busData(busData.Length - 2) Then Throw New EIB.Exceptions.EIBDataDecodeException("")

            _dataLength = busData(1)
            _data = New Byte(_dataLength - 2) {}

            For i As Integer = 1 To _dataLength - 1
                _data(i - 1) = busData(4 + i)
            Next
        End Sub


        Public ReadOnly Property DataLength As Byte
            Get
                Return _dataLength
            End Get
        End Property

        Public ReadOnly Property Data As Byte()
            Get
                Return _data
            End Get
        End Property


        Private Function CalculateCheckSum() As Byte
            Return CalculateCheckSum(_FT12_Data)
        End Function

        Public Shared Function CalculateCheckSum(data As Byte()) As Byte
            Dim checksum As UInteger = data(4)
            For i = 5 To data.Length - 3
                checksum += data(i)
            Next
            Return (checksum And &HFF)
        End Function


        Public Overrides Function ToInfoList() As List(Of InfoBase)
            Dim list As New List(Of InfoBase)

            list.Add(New Info("Type", String.Format("{0} (0x{0:X})", Type)))
            list.Add(New Info("Direction", String.Format("{0} (0x{0:X})", Direction)))
            list.Add(New Info("IsPrimary", PrimaryMessage))
            list.Add(New Info("FCB", ToggleFCB))
            list.Add(New Info("FCV", FCV))
            list.Add(New Info("FT1.2 Message Code", String.Format("{0} (0x{0:X})", MessageCode)))
            list.Add(New Info("Data length", DataLength))

            Dim msg As EIBBusData_FrameBase = Nothing

            Select Case EIBBusData_FrameBase.GetMessageType(_data)
                Case EIB.BusData.EIBBusData_EMICode.L_Data_con, EIB.BusData.EIBBusData_EMICode.L_Data_ind, EIB.BusData.EIBBusData_EMICode.L_Data_req
                    msg = New EIBBusData_FrameLData(Data)
                Case EIB.BusData.EIBBusData_EMICode.L_Busmon_ind
                    msg = New EIBBusData_FrameLBusMonData(Data)
            End Select

            If msg IsNot Nothing Then
                Dim datalist As New List(Of InfoBase)
                list.Add(New InfoList("Data", msg.GetType.Name, msg.ToInfoList))
            Else
                Dim dataList As New List(Of InfoBase)
                list.Add(New InfoList("Data", "", dataList))
                dataList.Add(New Info("Code", String.Format("{0} (0x{0:X})", EIBBusData_FrameBase.GetMessageType(Data))))
                dataList.Add(New InfoMessage(""))
                dataList.Add(New InfoMessage("- not supported, unknown message code -"))
            End If

            Return list
        End Function
    End Class
End Namespace